<?php

namespace App\Listeners\Plane\PlaneOrder;

use App\Events\Plane\PlaneOrder\PlaneOrderChangeNeedPayEvent;
use App\Models\Plane\PlaneOrderPassengers\PlaneOrderPassenger;
use App\Models\Plane\PlaneOrderPassengers\Repositories\Interfaces\PlaneOrderPassengerRepositoryInterface;
use App\Models\Plane\PlaneOrders\ChangeNeedPay;
use App\Trip\Enums\Plane\PlaneProviders;
use Exception;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;

class PlaneOrderChangeNeedPayListener
{
    /**
     * Create the event listener.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Handle the event.
     *
     * @param object $event
     * @return void
     * @throws GuzzleException
     */
    public function handle(PlaneOrderChangeNeedPayEvent $event)
    {
        // 验证需要支付的
        $notify           = $event->notify;
        $order_info       = $event->order;
        $service          = PlaneProviders::from($order_info->getOrderService())->getPlaneOrderStrategy();
        $sub_out_order_id = $notify->getChangeNo();// 变更单号作为改签订单的 子单号
        // 原订单
        $origin_order_info = $order_info->getOriginOrderInfo();
        $pay_amount        = $notify->getNeedPayPrice();
        // 先添加到数据库
        $need_pay        = new ChangeNeedPay();
        $need_pay_record = $need_pay->create([
            "order_sn"                => $order_info->getOrderSn(),
            "out_order_id"            => $order_info->getOutOrderId(),
            "sub_out_order_id"        => $sub_out_order_id,
            "origin_order_sn"         => $origin_order_info->getOutOrderId(),
            "origin_out_order_id"     => $notify->getOriginOutOrderId(),
            "origin_sub_out_order_id" => $notify->getOriginSubOutOrderId(),
            "need_pay_amount"         => $pay_amount,
            "state"                   => 1,
        ]);

        /**
         * @var Collection $passengers 订单乘客
         * @var Collection $relation_passengers 改签需支付的关联乘客
         * @var array      $sub_out_order_ids 外部子单号
         * @var int        $waiting_pay_num 待支付数量
         */
        $passengers              = $order_info->passengers;
        $relation_passengers     = collect($passengers)->where('sub_out_order_id', $sub_out_order_id);
        $planeOrderPassengerRepo = app(PlaneOrderPassengerRepositoryInterface::class);
        $sub_out_order_ids       = collect($passengers)->pluck('sub_out_order_id')->unique()->toArray();
        if (!in_array($sub_out_order_id, $sub_out_order_ids)) {
            Log::error("变更需支付,订单不存在:{$sub_out_order_id}");
            return;
        }

        // 如果有多个批次
        $waiting_pay_num = collect($passengers)->where('sub_out_order_id', '!=', $sub_out_order_id)->where('provider_change_pay_status', PlaneOrderPassenger::PROVIDER_CHANGE_PAY_STATUS_WAITING_PAY)->count();
        // 验证价格
        foreach ($relation_passengers as $passenger) {
            // 计算票价并更新
            $calc_ticket = round($pay_amount / $relation_passengers->count(), 2);
            $planeOrderPassengerRepo->updatePassenger($passenger, [
                'provider_change_pay_status' => PlaneOrderPassenger::PROVIDER_CHANGE_PAY_STATUS_WAITING_PAY,            // 乘客支付状态改为待支付
                'provider_ticket_price'      => $calc_ticket, // 支付金额 / 人数
            ]);
        }

        if ($waiting_pay_num == collect($passengers)->count()) {
            $calc = [];
            foreach ($relation_passengers as $passenger) {
                if (!isset($calc[$passenger['sub_out_order_id']])) {
                    $calc[$passenger['sub_out_order_id']] = [
                        'sub_out_order_id'        => $passenger['sub_out_order_id'],
                        'total_price'             => $passenger['total_price'],
                        'origin_sub_out_order_id' => $passenger['origin_sub_out_order_id'],
                        'out_change_id'           => $passenger['out_change_id'],
                        'provider_passenger_id'   => [
                            $passenger['provider_passenger_id'],
                        ],
                    ];
                } else {
                    $calc[$passenger['sub_out_order_id']]['total_price']             += $passenger['total_price'];
                    $calc[$passenger['sub_out_order_id']]['provider_passenger_id'][] = $passenger['provider_passenger_id'];
                }
            }

            /**
             * 将支付成功的结果压入数组
             */
            $ret = [];
            try {
                foreach ($calc as $item) {
                    $pay_res = $service->change_pay($order_info, [
                        "out_order_id"          => $item['origin_sub_out_order_id'],       // 原订单 51book need
                        "out_order_sn"          => $item['sub_out_order_id'],              // 变更单号 51book need
                        "pay_amount"            => $item['total_price'],                   // 支付金额  51book need
                        "out_change_id"         => $item['out_change_id'], // qunar  gqid
                        "provider_passenger_id" => $item['provider_passenger_id'], // qunar  provider_passenger_id
                    ]);

                    $ret[]                               = $item;
                    $order_info->provider_pay_state      = 5;// 更新订单状态为部分支付成功
                    $order_info->provider_pay_state_desc = "{$item['sub_out_order_id']},已支付";
                    $order_info->save();
                }
                // 更新订单状态为供应商已支付
                $order_info->provider_pay_state = 1;
                $order_info->save();
                // 更新当前支付记录状态 为支付成功
                $need_pay_record->state = 2;
                $need_pay_record->save();
            } catch (Exception $exception) {
                // 异常 就取消支付
                foreach ($ret as $item) {
                    // 这里先打个日志 可能需要发送短信
                    Log::error("机票变更需支付,服务商支付失败,对已支付无法取消,code:{$exception->getCode()},{$exception->getMessage()}");

                }
            }

        }
    }
}
